function getBoundingClientRect(element) {
    var rect = element.getBoundingClientRect();

    // whether the IE version is lower than 11
    var isIE = navigator.userAgent.indexOf("MSIE") != -1;

    // fix ie document bounding top always 0 bug
    var rectTop = isIE && element.tagName === 'HTML'
        ? -element.scrollTop
        : rect.top;

    return {
        left: rect.left,
        top: rectTop,
        right: rect.right,
        bottom: rect.bottom,
        width: rect.right - rect.left,
        height: rect.bottom - rectTop
    };
}

export default {
    install: function (Vue, options) {
        const wrapClass = '__contextmenu__'
        const itemClass = '__contextmenu-item__'
        const wrapEl = document.createElement('div')

        let docClick

        let binds = {}

        const style = "position: absolute;background: rgb(235,235,235); min-width: 100px; border-radius: 4px;"+ 
        "z-index: 99999; color: #606266; line-height: 1.4;opacity:0;"+
        "text-align: justify; font-size: 14px; box-shadow:rgba(0, 0, 0, 0.3) 0px 4px 10px 0px; word-break: break-all;"+
        "transition:opacity 300ms;-webkit-transition:opacity 300ms;padding:5px 0;display:none"
        const itemStyle = "height:24px;line-height:24px;padding:0 15px;cursor: pointer;"

        const styleEl = document.createElement('style')
        styleEl.innerHTML += "."+wrapClass+'{'+ style +'}'
        styleEl.innerHTML += "."+itemClass+'{'+ itemStyle +'}'
        styleEl.innerHTML += "."+itemClass+':hover{ background:#548ef0;color:#fff }'
        document.head.appendChild(styleEl)

        wrapEl.className = wrapClass
        //548ef0
        document.body.appendChild(wrapEl);
        function hide(){
            wrapEl.style.opacity = 0
            setTimeout(()=>{
                wrapEl.style = ''
            },100) 
        }
        function elContextmenu(e){
            var e = event || window.event;
            e.stopPropagation();//阻止冒泡事件
            e.cancelBubble = true;//阻止冒泡事件ie
            e.preventDefault();//阻止默认事件
            const { nodeId } = this.dataset
            const binding = binds[nodeId]
            const options = binding.value || []
            const _options = options.map((item,index)=>{
                if(item.label){
                    return '<div class="'+itemClass+'" data-index="'+index+'" data-value="'+item.value+'">'+ item.label +'</div>'
                }else{
                    return '<div style="width:100%;height:1px;background:#ccc;margin:5px 0"></div>'
                }
            }).join('')

            wrapEl.innerHTML = _options
            wrapEl.setAttribute('data-node-id',nodeId)
            wrapEl.style.top = 0
            wrapEl.style.left = 0
            const cRect = getBoundingClientRect(wrapEl);
            const wRect = { width:window.innerWidth,height:window.innerHeight }

            var menuX = e.pageX || e.pageY ? e.pageX : e.clientX + document.body.scrollLeft - document.body.clientLeft;//获取pageX 兼容ie
            var menuY = e.pageX || e.pageY ? e.pageY : e.clientY + document.body.scrollTop - document.body.clientTop;

            const canRight = wRect.width > menuX + cRect.width
            const canBottom = wRect.height > menuY + cRect.height

            if(!canRight)menuX = menuX - cRect.width
            if(!canBottom)menuY = menuY - cRect.height

            wrapEl.style.top = menuY+'px'
            wrapEl.style.left = menuX+'px'
            wrapEl.style.display = 'block'

            this.focus() 
            wrapEl.style.opacity = 1

        }
        function fnWrapClick(e){
            const target = e.target
            const classList = Array.prototype.slice.call(target.classList)
            const {nodeId} = this.dataset
            const binding = binds[nodeId]
            const { contextmenuclick,value } = binding
            if(classList.includes(itemClass)){
                const { index } = target.dataset
                const fn = value[index]['callback']
                fn && fn(value[index])
                if(contextmenuclick){
                    contextmenuclick(value[index])
                }
                hide()
            }
            
        }
        function bindData(el, binding, vnode){
            let _uid = vnode.componentInstance._uid
            let _contextmenuclick = undefined
            if(vnode.componentOptions && vnode.componentOptions.listeners && vnode.componentOptions.listeners.contextmenuclick){
                _contextmenuclick = vnode.componentOptions.listeners.contextmenuclick
            } 

            binds[_uid] = {
                value:binding.value,
                contextmenuclick:_contextmenuclick
            }
            el.setAttribute('data-node-id',_uid)
        }
        window.addEventListener('blur',hide)
        wrapEl.addEventListener('click',fnWrapClick)

        
        
        Vue.directive("contextmenu", {
            bind(el, binding, vnode) {
                bindData(el, binding, vnode)
                
                if(typeof el.tabindex === 'undefined')el.setAttribute('tabindex','0')
                el.addEventListener('contextmenu',elContextmenu)
                el.addEventListener('click',hide)
                document.addEventListener('click',docClick = e=>{
                    if(!e.path.includes(wrapEl)){
                        hide()       
                    }
                })
                
            },
            update(el, binding, vnode){
                bindData(el, binding, vnode) 
            },
            unbind(el, binding, vnode) {
                // wrapEl.removeEventListener('click',fnWrapClick) 
                el.removeEventListener('contextmenu',elContextmenu) 
                el.removeEventListener('click',hide)
                document.removeEventListener('click',docClick)

                hide()
            }
        })
    },
     
}